#ifndef PSDLITE_INCLUDED
#define PSDLITE_INCLUDED

// Copyright (c) 2007, Nils Jonas Norberg, See COPYING.txt for details

// USAGE
//
// psdlite::layered_image img;
// error_code err = load_layered_image( img, "test.psd" );
//
// your img is now filled with the pixel data and names of the layers of test.psd

#include <string>
#include <vector>

namespace psdlite
{

	typedef unsigned char u8;
	typedef unsigned short u16;
	typedef unsigned int u32;

	typedef char s8;
	typedef short s16;
	typedef int s32;

	struct vi2
	{
		vi2():x(0),y(0){}
		vi2(int w, int h) { set(w,h); }
		void set(int w, int h) { x = w; y = h; }
		int x,y;
	};

	struct pixel
	{
		static const u32 CHANNELS = 4;
		pixel()
		{
			for ( u32 i = 0 ; i != CHANNELS ; ++i)
				v[i] = 128;
		};

		u8 a(){ return v[0]; }
		u8 r(){ return v[1]; }
		u8 g(){ return v[2]; }
		u8 b(){ return v[3]; }

		u8 v[CHANNELS];
	};

	struct bitmap
	{
		bitmap()
		{
		}

		bitmap(int width, int height) { resize( width, height ); }

		void resize(int width, int height)
		{
			size_.set(width,height);
			data_.resize(width*height);
		}

		const pixel get_pixel(int x, int y) const
		{
			if (0 <= x && x < size_.x && 0 <= y && y < size_.y)
				return data_[ y * size_.x + x];
			return pixel();
		}

		void set_pixel(int x, int y, const pixel& p)
		{
			if (0 <= x && x < size_.x && 0 <= y && y < size_.y)
				data_[ y * size_.x + x] = p;
		}

		void set_single_channel(int x, int y, u32 channel, u8 v)
		{
			if (0 <= x && x < size_.x && 0 <= y && y < size_.y && channel < pixel::CHANNELS )
				data_[ y * size_.x + x].v[channel] = v;
		}

		void set_channel_count( u32 channel_count )
		{
			channel_count_ = channel_count;
		}

		u32 get_channel_count()
		{
			return channel_count_;
		}

		const vi2& get_size() const
		{
			return size_;
		}

	private:
		std::vector<pixel> data_;
		vi2 size_;
		u32 channel_count_;
	};

	struct layer
	{
		std::string name_;
		vi2 offs_;
		bitmap data_;
		u8 opacity_;
		u8 flags_;
	};

	struct layered_image
	{
		vi2 size_;
		std::vector<layer> layers_;
	};

	enum error_code
	{
		error_code_no_error,
		error_code_not_supported,
		error_code_invalid_file,
	};

	error_code load_layered_image( layered_image& dest, const char* fname );
}

#endif // PSDLITE_INCLUDED
